package gugga.tasks
{
	import flash.events.EventDispatcher;
	import flash.external.ExternalInterface;
	
	import gugga.tasks.events.TaskEvent;
	import gugga.eventHelpers.EventRethrower;
	
	[Event(name="start", type="TaskEvent")]
	[Event(name="interrupted", type="TaskEvent")]
	[Event(name="completed", type="TaskEvent")]
	
	/**
	 * <code>MonitoringTask</code> monitors the execution of an <code>ITask</code>. 
	 * <p>
	 * It is used in cases when we don't know whether a task is started, but we should monitor 
	 * for its <b><i>start</i></b>, <b><i>interrupted</i></b> or <b><i>completed</i></b>-events, 
	 * in order to use this task as part of a sequence or other kind of a tasks container. 
	 * Using an already started task without wrapping it in a <code>MonitoringTask</code> will 
	 * cause this task to attemp to start again and try to execute one more time. 
	 */
	public class MonitoringTask extends EventDispatcher implements ITask
	{
		protected var mMonitoredTask : ITask;
		
		public function MonitoringTask(aMonitoredTask : ITask)
		{
			super();
			
			mMonitoredTask = aMonitoredTask;
			
			EventRethrower.create(this, mMonitoredTask, TaskEvent.START);		
			EventRethrower.create(this, mMonitoredTask, TaskEvent.COMPLETED);
			EventRethrower.create(this, mMonitoredTask, TaskEvent.INTERRUPTED);
		}
		
		public function start() : void 
		{
			if(mMonitoredTask && mMonitoredTask.isRunning())
			{
				dispatchEvent(new TaskEvent(TaskEvent.START));
			}
		}
	
		public function isImmediatelyInterruptable() : Boolean 
		{
			return mMonitoredTask.isImmediatelyInterruptable();
		}
	
		public function interrupt() : void 
		{
			mMonitoredTask.interrupt();
		}
		
		public function isRunning() : Boolean 
		{
			return mMonitoredTask.isRunning();
		}
	}
}